package cn.fetosoft.woodpecker.core.pubsub.cluster;

import cn.fetosoft.woodpecker.core.jmeter.JMeterService;
import cn.fetosoft.woodpecker.core.pubsub.Command;
import cn.fetosoft.woodpecker.core.pubsub.zookeeper.AbstractZkSubscription;
import cn.fetosoft.woodpecker.core.pubsub.zookeeper.NodeEntity;
import cn.fetosoft.woodpecker.core.pubsub.zookeeper.ZookeeperCfg;
import cn.fetosoft.woodpecker.core.util.IpUtil;
import cn.fetosoft.woodpecker.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.zookeeper.CreateMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 节点注册
 * @author guobingbing
 * @wechat t_gbinb
 * @since 2021/9/12 13:53
 */
public class ClusterSubscription extends AbstractZkSubscription implements InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(ClusterSubscription.class);
    private NodeEntity entity = new NodeEntity();
    @Autowired
    private ZookeeperCfg cfg;
    @Autowired
    private JMeterService jMeterService;

    /**
     * 注册节点
     */
    private void register() throws Exception{
        entity.setId(RandomUtil.uuid());
        entity.setIp(IpUtil.getSingleLocalIP());
        entity.setPath(cfg.getRegPath() + "/" + entity.getIp());
        Runtime runtime = Runtime.getRuntime();
        entity.setCpuCore(runtime.availableProcessors());
        entity.setTotalMemory(runtime.totalMemory()/1024/1024);
        entity.setRegTime(System.currentTimeMillis());
        entity.setEnabled(true);
        this.createNode(entity.getPath(), CreateMode.EPHEMERAL, entity.toString());
    }

    @Override
    protected String getSubPath() {
        return cfg.getSubPath();
    }

    @Override
    protected String getRegPath() {
        return cfg.getRegPath();
    }

    @Override
    protected void subNodeChanged(ChildData oldData, ChildData data) {
        String dataJson = new String(data.getData());
        logger.info("Command==========>{}", dataJson);
        Command cmd = JSON.toJavaObject(JSON.parseObject(dataJson), Command.class);
        if(Command.CMD_ENABLED.equals(cmd.getCommand())){
            this.enabled(cmd);
        }else if(Command.CMD_START_TEST.equals(cmd.getCommand())){
            this.startTest(cmd);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.register();
        this.subscript();
    }

    /**
     * 是否启用
     * @param command
     */
    private void enabled(Command command){
        if(command.getClusterId().equals(this.entity.getId())) {
            this.entity.setEnabled(command.getEnabled());
            try {
                this.client.setData().forPath(this.entity.getPath(), entity.toString().getBytes(CHARSET));
            } catch (Exception e) {
                logger.error("enabled", e);
            }
        }
    }

    /**
     * 启动测试
     * @param command
     */
    private void startTest(Command command){
        if(this.entity.isEnabled()){
            try {
                jMeterService.startTest(command.getUserId(), command.getTestId(), command.getPlanId());
                logger.info("Start test success==========>{}", this.entity.getIp());
            } catch (Exception e) {
                logger.error("startTest", e);
            }
        }
    }
}
